package com.woniuxy.book.mq;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniuxy.book.entity.BookInfo;
import com.woniuxy.book.entity.OrderInfo;
import com.woniuxy.book.entity.OrderItem;
import com.woniuxy.book.mapper.BookInfoMapper;
import com.woniuxy.book.mapper.OrderInfoMapper;
import com.woniuxy.book.mapper.OrderItemMapper;
import com.woniuxy.book.service.dto.PayInfoDTO;
import com.woniuxy.book.util.AlipayUtil;
import com.woniuxy.book.util.RedisKeyUtil;
import com.woniuxy.book.util.StateData;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.TimeUnit;


@Component
public class HandlerOrderComsumer {

    @Resource
    private BookInfoMapper bookInfoMapper;
    @Resource
    private OrderInfoMapper orderInfoMapper;
    @Resource
    private OrderItemMapper orderItemMapper;
    @Resource
    private RedissonClient redissonClient;
    @Resource
    private AlipayUtil alipayUtil;

    @RabbitListener(
            bindings = {
                    @QueueBinding(
                            value = @Queue(name = "order-queue"),
                            exchange = @Exchange(name = "delay-ex"),
                            key = "order"
                    )
            })
    @Transactional
    public void handler(String orderNum) throws Exception {
        //消费队列中的订单
        //调用支付宝的接口判断本次订单的支付状态
        PayInfoDTO payInfoDTO = alipayUtil.selectPayState(orderNum);
        OrderInfo orderInfo = orderInfoMapper.selectById(orderNum);
        if (orderInfo!=null) {
            if ("TRADE_SUCCESS".equals(payInfoDTO.getPayState())) {
                if (orderInfo.getOrderState()== StateData.ORDER_STATE_NOPAY) {
                    //修改订单状态
                    orderInfo.setOrderState(StateData.ORDER_STATE_PAYED);
                    orderInfo.setPayTime(LocalDateTime.parse(payInfoDTO.getPayDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    orderInfoMapper.updateById(orderInfo);
                    //查询订单详情
                    QueryWrapper<OrderItem> wrapper= new QueryWrapper<>();
                    wrapper.eq("order_id",orderNum);
                    //排序防止死锁
                    wrapper.orderByAsc("book_id");
                    List<OrderItem> items = orderItemMapper.selectList(wrapper);
                    //创建多资源锁
                    RLock[] lockList = new RLock[items.size()];
                    for (int i = 0; i < items.size(); i++) {
                        RLock rLock = redissonClient.getFairLock(RedisKeyUtil.lockBookId(items.get(i).getBookId()));
                        lockList[i] = rLock;
                    }
                    RLock lock = redissonClient.getMultiLock(lockList);
                    try {
                        if (lock.tryLock(10, TimeUnit.SECONDS)) {
                            for (OrderItem item : items) {
                                BookInfo bookInfo = bookInfoMapper.selectById(item.getBookId());
                                bookInfo.setFreeze(bookInfo.getFreeze()-item.getBookCont());
                                bookInfoMapper.updateById(bookInfo);
                            }
                        }
                    } finally {
                        lock.unlock();
                    }
                }
            }else {//如果订单是没有支付的状态
                //修改订单状态
                orderInfo.setOrderState(StateData.ORDER_STATE_CANCEL);
                orderInfoMapper.updateById(orderInfo);
                //查询订单详情
                QueryWrapper<OrderItem> wrapper= new QueryWrapper<>();
                wrapper.eq("order_id",orderNum);
                //排序防止死锁
                wrapper.orderByAsc("book_id");
                List<OrderItem> items = orderItemMapper.selectList(wrapper);
                //创建多资源锁
                RLock[] lockList = new RLock[items.size()];
                for (int i = 0; i < items.size(); i++) {
                    RLock rLock = redissonClient.getFairLock(RedisKeyUtil.lockBookId(items.get(i).getBookId()));
                    lockList[i] = rLock;
                }
                RLock lock = redissonClient.getMultiLock(lockList);
                try {
                    if (lock.tryLock(10, TimeUnit.SECONDS)) {
                        for (OrderItem item : items) {
                            BookInfo bookInfo = bookInfoMapper.selectById(item.getBookId());
                            bookInfo.setFreeze(bookInfo.getFreeze()-item.getBookCont());
                            bookInfo.setNumber(bookInfo.getNumber()+item.getBookCont());
                            bookInfoMapper.updateById(bookInfo);
                        }
                    }
                } finally {
                    lock.unlock();
                }

            }
        }

    }
}
